home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
hobbes3
/
bitblt.asm
< prev
next >
Wrap
Assembly Source File
|
1992-08-24
|
18KB
|
488 lines
include hobbes.inc
include extrn.inc
.DATA
; Plane masks for clipping left and right edges of rectangle
LeftClipPlaneMask db 00fh,00eh,00ch,008h
RightClipPlaneMask db 00fh,001h,003h,007h
.CODE
;----------------------------------------------------------------------------
; void CopyScreenToScreenMaskedX(int SourceStartX,
; int SourceStartY, int SourceEndX, int SourceEndY,
; int DestStartX, int DestStartY, MaskedImage * Source,
; unsigned int DestPageBase, int DestBitmapWidth);
.code
public _CopyScreenToScreenMaskedX
_CopyScreenToScreenMaskedX proc far
ARG SourceStartX, SourceStartY, SourceEndX, SourceEndY, DestStartX, DestStartY, \
ImageWidth, ImagePtr, MaskPtr:DWORD
LOCAL SourceNextScanOffset, DestNextScanOffset, RectAddrWidth, \
RectHeight, SourceBitmapWidth = LocalStack
push bp
mov bp,sp
sub sp,LocalStack
push si
push di
push ds
mov ax,@data
mov ds,ax
cld
mov dx,GC_INDEX ;set the bit mask to select all bits
mov ax,00000h+BIT_MASK ; from the latches and none from
out dx,ax ; the CPU, so that we can write the
; latch contents directly to memory
mov ax,_ModeX_Segment ;point ES to display memory
mov es,ax
mov ax,_Virtual_Width_Addr
; shr ax,1 ;convert to width in addresses
; shr ax,1
mul DestStartY ;top dest rect scan line
mov di,DestStartX
mov si,di
shr di,1 ;X/4 = offset of first dest rect pixel in
shr di,1 ; scan line
add di,ax ;offset of first dest rect pixel in page
add di,_Draw_Offset ;offset of first dest rect pixel
; in display memory. now look up the image that's
; aligned to match left-edge alignment of destination
and si,3 ;DestStartX modulo 4
mov cx,si ;set aside alignment for later
shl si,1 ;prepare for word look-up
;*******vvvvvv
; mov bx,Source] ;point to source MaskedImage structure
; mov bx,[bx+Alignments+si] ;point to AlignedMaskedImage
; ; struc for current left edge alignment
; mov ax,[bx+ImageWidth] ;image width in addresses
; mov SourceBitmapWidth],ax ;remember image width in
; ; addresses
; mul SourceStartY] ;top source rect scan line
; push es
; les bx,Source
; mov bx,es:[bx+Alignments+si]
mov ax,ImageWidth
mov SourceBitmapWidth,ax
mul SourceStartY
;*******^^^^^^
mov si,SourceStartX
shr si,1 ;X/4 = address of first source rect pixel in
shr si,1 ; scan line
add si,ax ;offset of first source rect pixel in image
mov ax,si
;*******vvvvvv
; add si,[bx+MaskPtr] ;point to mask offset of first mask pixel in DS
; mov bx,[bx+ImagePtr] ;offset of first source rect pixel
; add si,es:[bx+MaskPtr]
; mov bx,es:[bx+ImagePtr]
mov bx,ImagePtr
; pop es
;*******^^^^^^
add bx,ax ; in display memory
mov ax,SourceStartX ;calculate # of addresses across
add ax,cx ; rect, shifting if necessary to
add cx,SourceEndX ; account for alignment
cmp cx,ax
jle CopyDone ;skip if 0 or negative width
add cx,3
and ax,not 011b
sub cx,ax
shr cx,1
shr cx,1 ;# of addresses across rectangle to copy
mov ax,SourceEndY
sub ax,SourceStartY ;AX = height of rectangle
jle CopyDone ;skip if 0 or negative height
mov RectHeight,ax
mov ax,_Virtual_Width_Addr
; shr ax,1 ;convert to width in addresses
; shr ax,1
sub ax,cx ;distance from end of one dest scan line to start of next
mov DestNextScanOffset,ax
mov ax,SourceBitmapWidth ;width in addresses
sub ax,cx ;distance from end of source scan line to start of next
mov SourceNextScanOffset,ax
mov RectAddrWidth,cx ;remember width in addresses
mov dx,SC_INDEX
mov al,MAP_MASK
out dx,al ;point SC Index register to Map Mask
inc dx ;point to SC Data register
;********
lds si,MaskPtr
;********
CopyRowsLoop:
mov cx,RectAddrWidth ;width across
CopyScanLineLoop:
lodsb ;get the mask for this four-pixel set
; and advance the mask pointer
out dx,al ;set the mask
mov al,es:[bx] ;load the latches with 4-pixel set from source
mov es:[di],al ;copy the four-pixel set to the dest
inc bx ;advance the source pointer
inc di ;advance the destination pointer
dec cx ;count off four-pixel sets
jnz CopyScanLineLoop
mov ax,SourceNextScanOffset
add si,ax ;point to the start of
add bx,ax ; the next source, mask,
add di,DestNextScanOffset ; and dest lines
dec word ptr RectHeight ;count down scan lines
jnz CopyRowsLoop
CopyDone:
mov dx,GC_INDEX+1 ;restore the bit mask to its default,
mov al,0ffh ; which selects all bits from the CPU
out dx,al ; and none from the latches (the GC
; Index still points to Bit Mask)
pop ds
pop di ;restore caller's register variables
pop si
mov sp,bp ;discard storage for local variables
pop bp ;restore caller's stack frame
ret
_CopyScreenToScreenMaskedX endp
;----------------------------------------------------------------------------
; void CopyScreenToScreen(int SourceStartX, int SourceStartY,
; int SourceEndX, int SourceEndY, int DestStartX,
; int DestStartY, unsigned int SourcePageBase,
; unsigned int DestPageBase, int SourceBitmapWidth,
; int DestBitmapWidth);
public _CopyScreenToScreen
_CopyScreenToScreen proc far
ARG @@SourceStartX:WORD, @@SourceStartY:WORD, @@SourceEndX:WORD, @@SourceEndY:WORD, \
@@DestStartX:WORD, @@DestStartY:WORD, \
@@SourcePageBase:WORD, @@DestPageBase:WORD, @@SourceWidth:WORD, @@DestWidth:WORD
LOCAL SourceNextScanOffset:WORD, DestNextScanOffset:WORD, \
RectAddrWidth:WORD, Height:WORD = LocalStack
push bp
mov bp,sp
sub sp,LocalStack
push si
push di
push ds
mov ax,@data
mov ds,ax
cld
mov dx,GC_INDEX ;set the bit mask to select all bits
mov ax,00000h+BIT_MASK ; from the latches and none from
out dx,ax ; the CPU, so that we can write the
; latch contents directly to memory
mov ax,_ModeX_Segment ;point ES to display memory
mov es,ax
mov ax,@@DestWidth
shr ax,1 ;convert to width in addresses
shr ax,1
mul @@DestStartY ;top dest rect scan line
mov di,@@DestStartX
shr di,1 ;X/4 = offset of first dest rect pixel in
shr di,1 ; scan line
add di,ax ;offset of first dest rect pixel in page
add di,@@DestPageBase ;offset of first dest rect pixel
; in display memory
mov ax,@@SourceWidth
shr ax,1 ;convert to width in addresses
shr ax,1
mul @@SourceStartY ;top source rect scan line
mov si,@@SourceStartX
mov bx,si
shr si,1 ;X/4 = offset of first source rect pixel in
shr si,1 ; scan line
add si,ax ;offset of first source rect pixel in page
add si,@@SourcePageBase ;offset of first source rect
; pixel in display memory
and bx,0003h ;look up left edge plane mask
mov ah,LeftClipPlaneMask[bx] ; to clip
mov bx,@@SourceEndX
and bx,0003h ;look up right edge plane
mov al,RightClipPlaneMask[bx] ; mask to clip
mov bx,ax ;put the masks in BX
mov cx,@@SourceEndX ;calculate # of addresses across
mov ax,@@SourceStartX ; rect
cmp cx,ax
jle @@CopyDone ;skip if 0 or negative width
dec cx
and ax,not 011b
sub cx,ax
shr cx,1
shr cx,1 ;# of addresses across rectangle to copy - 1
jnz @@MasksSet ;there's more than one address to draw
and bh,bl ;there's only one address, so combine the left
; and right edge clip masks
@@MasksSet:
mov ax,@@SourceEndY
sub ax,@@SourceStartY ;AX = height of rectangle
jle @@CopyDone ;skip if 0 or negative height
mov Height,ax
mov ax,@@DestWidth
shr ax,1 ;convert to width in addresses
shr ax,1
sub ax,cx ;distance from end of one dest scan line to
dec ax ; start of next
mov DestNextScanOffset,ax
mov ax,@@SourceWidth
shr ax,1 ;convert to width in addresses
shr ax,1
sub ax,cx ;distance from end of one source scan line to
dec ax ; start of next
mov SourceNextScanOffset,ax
mov RectAddrWidth,cx ;remember width in addresses - 1
mov dx,SC_INDEX+1 ;point to Sequence Controller Data reg
; (SC Index still points to Map Mask)
mov ax,es ;DS=ES=screen segment for MOVS
mov ds,ax
@@CopyRowsLoop:
mov cx,RectAddrWidth ;width across - 1
mov al,bh ;put left-edge clip mask in AL
out dx,al ;set the left-edge plane (clip) mask
movsb ;copy the left edge (pixels go through
; latches)
dec cx ;count off left edge address
js @@CopyLoopBottom ;that's the only address
jz @@DoRightEdge ;there are only two addresses
mov al,00fh ;middle addresses are drawn 4 pixels at a pop
out dx,al ;set the middle pixel mask to no clip
rep movsb ;draw the middle addresses four pixels apiece
; (pixels copied through latches)
@@DoRightEdge:
mov al,bl ;put right-edge clip mask in AL
out dx,al ;set the right-edge plane (clip) mask
movsb ;draw the right edge (pixels copied through
; latches)
@@CopyLoopBottom:
add si,SourceNextScanOffset ;point to the start of
add di,DestNextScanOffset ; next source & dest lines
dec word ptr Height ;count down scan lines
jnz @@CopyRowsLoop
@@CopyDone:
mov dx,GC_INDEX+1 ;restore the bit mask to its default,
mov al,0ffh ; which selects all bits from the CPU
out dx,al ; and none from the latches (the GC
; Index still points to Bit Mask)
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
_CopyScreenToScreen endp
;----------------------------------------------------------------------------
; void CopySystemToScreen(int SourceStartX, int SourceStartY,
; int SourceEndX, int SourceEndY, int DestStartX,
; int DestStartY, char* SourcePtr, unsigned int DestPageBase,
; int SourceBitmapWidth, int DestBitmapWidth);
public _CopySystemToScreen
_CopySystemToScreen proc far
ARG SourceStartX:WORD, SourceStartY:WORD, SourceEndX:WORD, SourceEndY:WORD, \
DestStartX:WORD, DestStartY:WORD, SourcePtr:DWORD, DestPageBase:WORD, \
SourceWidth:WORD, DestWidth:WORD
LOCAL RectWidth:WORD, LeftMask:WORD = LocalStack
push bp
mov bp,sp
sub sp,LocalStack
push si
push di
push ds
mov ax,@data
mov ds,ax
cld
mov ax,_ModeX_Segment ;point ES to display memory
mov es,ax
mov ax,SourceWidth
mul SourceStartY ;top source rect scan line
add ax,SourceStartX
;*********
; add ax,SourcePtr ;offset of first source rect pixel
lds bx,SourcePtr
add ax,bx
;*********
mov si,ax ; in DS
mov ax,DestWidth
shr ax,1 ;convert to width in addresses
shr ax,1
mov DestWidth,ax ;remember address width
mul DestStartY ;top dest rect scan line
mov di,DestStartX
mov cx,di
shr di,1 ;X/4 = offset of first dest rect pixel in
shr di,1 ; scan line
add di,ax ;offset of first dest rect pixel in page
add di,DestPageBase ;offset of first dest rect pixel
; in display memory
and cl,011b ;CL = first dest pixel's plane
mov al,11h ;upper nibble comes into play when plane wraps
; from 3 back to 0
shl al,cl ;set the bit for the first dest pixel's plane
cbw
mov LeftMask,ax ; in each nibble to 1
mov cx,SourceEndX ;calculate # of pixels across
sub cx,SourceStartX ; rect
jle @@CopyDone ;skip if 0 or negative width
mov RectWidth,cx
mov bx,SourceEndY
sub bx,SourceStartY ;BX = height of rectangle
jle @@CopyDone ;skip if 0 or negative height
mov dx,SC_INDEX ;point to SC Index register
mov al,MAP_MASK
out dx,al ;point SC Index reg to the Map Mask
inc dx ;point DX to SC Data reg
@@CopyRowsLoop:
mov ax,LeftMask
mov cx,RectWidth
push si ;remember the start offset in the source
push di ;remember the start offset in the dest
@@CopyScanLineLoop:
out dx,al ;set the plane for this pixel
movsb ;copy the pixel to the screen
rol al,1 ;set mask for next pixel's plane
cmc ;advance destination address only when
sbb di,0 ; wrapping from plane 3 to plane 0
; (else undo INC DI done by MOVSB)
loop @@CopyScanLineLoop
pop di ;retrieve the dest start offset
add di,DestWidth ;point to the start of the
; next scan line of the dest
pop si ;retrieve the source start offset
add si,SourceWidth ;point to the start of the
; next scan line of the source
dec bx ;count down scan lines
jnz @@CopyRowsLoop
@@CopyDone:
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
_CopySystemToScreen endp
;----------------------------------------------------------------------------
; void CopySystemToScreenMasked(int SourceStartX,
; int SourceStartY, int SourceEndX, int SourceEndY,
; int DestStartX, int DestStartY, char * SourcePtr,
; unsigned int DestPageBase, int SourceBitmapWidth,
; int DestBitmapWidth, char * MaskPtr);
.code
public _CopySystemToScreenMasked
_CopySystemToScreenMasked proc far
ARG SourceStartX:WORD, SourceStartY:WORD, SourceEndX:WORD, SourceEndY:WORD, \
DestStartX:WORD, DestStartY:WORD, SourcePtr:WORD, DestPageBase:WORD, \
SourceWidth:WORD, DestWidth:WORD, MaskP:WORD
LOCAL RectWidth:WORD, RectHeight:WORD, LeftMask:WORD = LocalStack
push bp
mov bp,sp
sub sp,LocalStack
push si
push di
push ds
mov ax,@data
mov ds,ax
mov ax,_ModeX_Segment ;point ES to display memory
mov es,ax
mov ax,SourceWidth
mul SourceStartY ;top source rect scan line
add ax,SourceStartX
mov bx,ax
add ax,SourcePtr ;offset of first source rect pixel
mov si,ax ; in DS
add bx,MaskP ;offset of first mask pixel in DS
mov ax,DestWidth
shr ax,1 ;convert to width in addresses
shr ax,1
mov DestWidth,ax ;remember address width
mul DestStartY ;top dest rect scan line
mov di,DestStartX
mov cx,di
shr di,1 ;X/4 = offset of first dest rect pixel in
shr di,1 ; scan line
add di,ax ;offset of first dest rect pixel in page
add di,DestPageBase ;offset of first dest rect pixel
; in display memory
and cl,011b ;CL = first dest pixel's plane
mov al,11h ;upper nibble comes into play when plane wraps
; from 3 back to 0
shl al,cl ;set the bit for the first dest pixel's plane
cbw
mov LeftMask,ax ; in each nibble to 1
mov ax,SourceEndX ;calculate # of pixels across
sub ax,SourceStartX ; rect
jle @@CopyDone ;skip if 0 or negative width
mov RectWidth,ax
sub word ptr SourceWidth,ax
;distance from end of one source scan line to start of next
mov ax,SourceEndY
sub ax,SourceStartY ;height of rectangle
jle @@CopyDone ;skip if 0 or negative height
mov RectHeight,ax
mov dx,SC_INDEX ;point to SC Index register
mov al,MAP_MASK
out dx,al ;point SC Index reg to the Map Mask
inc dx ;point DX to SC Data reg
@@CopyRowsLoop:
mov ax,LeftMask
mov cx,RectWidth
push di ;remember the start offset in the dest
@@CopyScanLineLoop:
cmp byte ptr [bx],0 ;is this pixel mask-enabled?
jz @@MaskOff ;no, so don't draw it
;yes, draw the pixel
out dx,al ;set the plane for this pixel
mov ah,[si] ;get the pixel from the source
mov es:[di],ah ;copy the pixel to the screen
@@MaskOff:
inc bx ;advance the mask pointer
inc si ;advance the source pointer
rol al,1 ;set mask for next pixel's plane
adc di,0 ;advance destination address only when
; wrapping from plane 3 to plane 0
loop @@CopyScanLineLoop
pop di ;retrieve the dest start offset
add di,DestWidth ;point to the start of the
; next scan line of the dest
add si,SourceWidth ;point to the start of the
; next scan line of the source
add bx,SourceWidth ;point to the start of the
; next scan line of the mask
dec word ptr RectHeight ;count down scan lines
jnz @@CopyRowsLoop
@@CopyDone:
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
_CopySystemToScreenMasked endp
;----------------------------------------------------------------------------
END